package com.heima.brhavior.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.model.mess.UpdateArticleMess.UpdateArticleType;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.heima.brhavior.service.ApBehaviorEntryService;
import com.heima.brhavior.service.ApLikesBehaviorService;
import com.heima.common.constants.article.HotArticleConstants;
import com.heima.common.constants.user.UserRelationConstants;
import com.heima.model.behavior.dtos.BehaviorDTO;
import com.heima.model.behavior.dtos.CollectionDto;
import com.heima.model.behavior.pojos.*;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.mess.UpdateArticleMess;
import com.heima.model.threadlocal.WmThreadLocalUtils;
import com.heima.model.wemedia.pojos.WmUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * @author lo
 * @date 2021/9/29
 */
@Service
@Slf4j
public class ApLikesBehaviorServiceImpl implements ApLikesBehaviorService {
    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    ApBehaviorEntryService apBehaviorEntryService;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    /**
     * 点赞,取消点赞
     *
     * @param likesBehaviorDTO 设备id  文章id 内容类型 点赞还是取消点赞
     * @return
     */
    @Override
    public ResponseResult likeBehavior(BehaviorDTO likesBehaviorDTO) {

        //1.获取当前登录用户id
        Integer loginId = this.loginId();
        //2.校验参数
        if (likesBehaviorDTO.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //3.获取行为实体
        ApBehaviorEntry byUserIdOrEquipmentId = apBehaviorEntryService.findByUserIdOrEquipmentId(loginId, likesBehaviorDTO.getEquipmentId());
        Integer entryId = byUserIdOrEquipmentId.getEntryId();

        //4.判断是什么行为
        if (likesBehaviorDTO.getOperation() == 0) {
            //点赞行为,添加数据
            ApLikesBehavior apLikesBehavior = new ApLikesBehavior();
            apLikesBehavior.setEntryId(entryId);
            apLikesBehavior.setArticleId(likesBehaviorDTO.getArticleId());
            apLikesBehavior.setType((short) 0);
            apLikesBehavior.setOperation((short) 0);
            apLikesBehavior.setCreatedTime(new Date());
            apLikesBehavior.setEquipmentId(likesBehaviorDTO.getEquipmentId());
            mongoTemplate.save(apLikesBehavior);


        }
        if (likesBehaviorDTO.getOperation() == 1) {
            //取消点赞,删除对应的行为
            mongoTemplate.remove(
                    Query.query(Criteria
                            .where("entryId").is("entryId")
                            .and("articleId").is(likesBehaviorDTO.getArticleId())),
                    ApLikesBehavior.class);
        }
        //发送消息给消息采集队列
        //1.封装对应点赞实体类
        UpdateArticleMess updateArticleMess = new UpdateArticleMess();
        updateArticleMess.setType(UpdateArticleType.LIKES);
        updateArticleMess.setArticleId(likesBehaviorDTO.getArticleId());
        updateArticleMess.setAdd(likesBehaviorDTO.getOperation() == 0 ? 1 : -1);
        //2.发送消息
        rabbitTemplate.convertAndSend(HotArticleConstants.HOT_ARTICLE_SCORE_BEHAVIOR_QUEUE, JSON.toJSONString(updateArticleMess));

        return ResponseResult.okResult();
    }

    /**
     * 保存阅读行为
     *
     * @param readBehaviorDto 文章id 设备id
     * @return
     */
    @Override
    public ResponseResult readBehavior(BehaviorDTO readBehaviorDto) {
        //1.获取当前用户的id
        Integer loginId = this.loginId();
        //2.校验参数
        if (readBehaviorDto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //3.查询对应的实体
        ApBehaviorEntry apBehaviorEntry = apBehaviorEntryService.findByUserIdOrEquipmentId(loginId, readBehaviorDto.getEquipmentId());

        //4.根据对应的实体封装阅读行为参数
        ApReadBehavior apReadBehavior = new ApReadBehavior();
        apReadBehavior.setEntryId(apBehaviorEntry.getEntryId());
        apReadBehavior.setArticleId(readBehaviorDto.getArticleId());
        apReadBehavior.setCount((short) 0);
        apReadBehavior.setReadDuration(0);
        apReadBehavior.setPercentage((short) 0);
        apReadBehavior.setLoadDuration(0);
        apReadBehavior.setCreatedTime(new Date());
        apReadBehavior.setUpdatedTime(new Date());

        //5.存入MongoDB数据库
        mongoTemplate.save(apBehaviorEntry);

        //6.发送消息给信息采集
        //1.封装对应点赞实体类
        UpdateArticleMess updateArticleMess = new UpdateArticleMess();
        updateArticleMess.setType(UpdateArticleType.VIEWS);
        updateArticleMess.setArticleId(readBehaviorDto.getArticleId());
        updateArticleMess.setAdd(1);
        //2.发送消息
        rabbitTemplate.convertAndSend(HotArticleConstants.HOT_ARTICLE_SCORE_BEHAVIOR_QUEUE, JSON.toJSONString(updateArticleMess));


        return ResponseResult.okResult();

    }

    /**
     * 不喜欢行为
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult unLikeBehavior(BehaviorDTO dto) {
        //1.获取用户id;
        Integer loginId = this.loginId();
        //2.查询对应实体
        ApBehaviorEntry apBehaviorEntry = apBehaviorEntryService.findByUserIdOrEquipmentId(loginId, dto.getEquipmentId());
        //3.校验参数
        if (dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //4.通过实体封装不喜欢的实体类;
        ApUnlikesBehavior apUnlikesBehavior = new ApUnlikesBehavior();
        apUnlikesBehavior.setEntryId(apBehaviorEntry.getEntryId());
        apUnlikesBehavior.setArticleId(dto.getArticleId());
        apUnlikesBehavior.setType((short) 0);
        apUnlikesBehavior.setCreatedTime(new Date());

        //5.存入MongoDB数据库
        mongoTemplate.save(apBehaviorEntry);
        return ResponseResult.okResult();
    }

    /**
     * 收藏行为 API
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult collectionBehavior(CollectionDto dto) {
        //1.获取用户id
        Integer loginId = this.loginId();

        //2.查询对应实体
        ApBehaviorEntry byUserIdOrEquipmentId = apBehaviorEntryService.findByUserIdOrEquipmentId(loginId, dto.getEquipmentId());

        //3.判断是否是收藏
        CollectionBehavior collectionBehavior = new CollectionBehavior();
        if (dto.getOperation() == 0) {
            //收藏
            collectionBehavior.setEntryId(byUserIdOrEquipmentId.getEntryId());
            collectionBehavior.setArticleId(dto.getEntryId());
            collectionBehavior.setType((short) 0);
            collectionBehavior.setOperation((short) 0);
            collectionBehavior.setCreatedTime(new Date());
            collectionBehavior.setEquipmentId(dto.getEquipmentId());
            mongoTemplate.save(collectionBehavior);
        } else {
            // 取消收藏
            //根据文章删除收藏数据
            Query query = Query.query(Criteria.where("articleId").is(dto.getEntryId()).and("entryId").is(byUserIdOrEquipmentId.getEntryId()));
            mongoTemplate.remove(query, CollectionBehavior.class);
        }
        //发送消息给信息采集
        //1.封装对应点赞实体类
        UpdateArticleMess updateArticleMess = new UpdateArticleMess();
        updateArticleMess.setType(UpdateArticleType.COLLECTION);
        updateArticleMess.setArticleId(dto.getEntryId());
        updateArticleMess.setAdd(dto.getOperation() == 0 ? 1 : -1);
        //2.发送消息
        rabbitTemplate.convertAndSend(HotArticleConstants.HOT_ARTICLE_SCORE_BEHAVIOR_QUEUE, JSON.toJSONString(updateArticleMess));


        return ResponseResult.okResult();
    }

    /**
     * 查询文章行为信息
     *
     * @param dto 文章id 文章作者id 文章作者的userID 设备id
     * @return
     */
    @Override
    public ResponseResult loadArticleBehavior(BehaviorDTO dto) {
        //1.校验参数
        if (dto.getArticleId() == null || dto.getAuthorApUserId() == null || dto.getAuthorId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //2.获取登录用户id
        Integer loginId = this.loginId();
        //3.查询行为实体id
        ApBehaviorEntry byUserIdOrEquipmentId = apBehaviorEntryService.findByUserIdOrEquipmentId(loginId, dto.getEquipmentId());
        Integer entryId = byUserIdOrEquipmentId.getEntryId();
        //4.查询行为
        //4.1 查询是否点赞
        Query query = Query.query(Criteria.where("entryId").is(entryId).and("articleId").is(dto.getArticleId()));
        ApLikesBehavior likesBehavior = mongoTemplate.findOne(query, ApLikesBehavior.class);
        //5.封装参数
        Map<String, Boolean> map = new HashMap<>(8);
        if (likesBehavior == null) {
            //说明没有点赞
            map.put("islike", false);
        } else {
            map.put("islike", true);
        }
        //4.2 查询是否关注
        Double score = redisTemplate.opsForZSet().score(UserRelationConstants.FOLLOW_LIST + loginId, dto.getAuthorApUserId() + "");
        if (score == null) {
            //说明没有关注过
            map.put("isfollow", false);
        } else {
            map.put("isfollow", true);
        }
        //4.3 查询是否不喜欢
        ApUnlikesBehavior apUnlikesBehavior = mongoTemplate.findOne(query, ApUnlikesBehavior.class);
        if (apUnlikesBehavior == null) {
            map.put("isunlike", false);
        } else {
            map.put("isunlike", true);
        }
        //4.4 查询是否收藏
        CollectionBehavior collectionBehavior = mongoTemplate.findOne(query, CollectionBehavior.class);
        if (collectionBehavior == null) {
            map.put("iscollection", false);
        } else {
            map.put("iscollection", true);

        }
        return ResponseResult.okResult(map);
    }


    /**
     * 获取用户id
     */
    public Integer loginId() {
        WmUser user = WmThreadLocalUtils.getUser();
        Integer loginId = null;
        if (user != null) {
            loginId = user.getId();
        }
        return loginId;
    }
}
